/*
 * Alexey Danchuk
 * This software is an implementation of the task from OOP module.
 */
package repository;

import question.*;

/**
 * This class describes single questions repository for system.
 *
 * @version 1.01 19 February 2013
 * @author Alexey Danchuk
 */
public class QuestionsRepository {

    /**
     * Implementation of a singleton pattern must satisfy the single instance
     * and global access principles.
     */
    private static QuestionsRepository instance = null;
    /**
     * The default capacity for test system.
     */
    private static final int DEFAULT_CAPACITY = 10;
    /**
     * The number of questions in this repository.
     *
     * @serial the list size
     */
    private int size;
    /**
     * Questions for test.
     */
    private Question[] systemQuestions;

    /**
     * Private constructor prevents instantiation from other classes.
     */
    private QuestionsRepository() {
        // Empty questions for test system with default capasity
        this.systemQuestions = new Question[DEFAULT_CAPACITY];
        this.size = 0;
    }

    public static QuestionsRepository getInstance() {
        synchronized (QuestionsRepository.class) {
            if (instance == null) {
                instance = new QuestionsRepository();
            }
        }
        return instance;
    }
    
    public Question[] resize(final Question[] ourSource, final int newLength) {
        if ((newLength < 0) || (newLength < DEFAULT_CAPACITY)
                            || (newLength < this.systemQuestions.length)) {
            throw new IllegalArgumentException("Illegal Capacity: "
                    + newLength);
        }
        Question[] newSystemQuestion = new Question[newLength];
        System.arraycopy(ourSource, 0, newSystemQuestion, 
                0, this.systemQuestions.length);
        return newSystemQuestion;
    }
    
    private boolean lastFree(Question question) {
        for (int i = 0; i < this.systemQuestions.length; i++) {
            if (systemQuestions[i] == null) {
                systemQuestions[i] = question;
                break;
            }
        }
        return true;
    }
    
    public void add(Question ourQuesition) {
        if (this.systemQuestions[systemQuestions.length - 1] == null) {
            boolean lastFree = lastFree(ourQuesition);
            this.size++;
            if (lastFree != true) {
                System.err.println("Adding a new question to the system failed");
            }
        } else {
            this.systemQuestions = resize(systemQuestions,
                    systemQuestions.length + DEFAULT_CAPACITY);
            boolean lastFree = lastFree(ourQuesition);
            this.size++;
            if (lastFree != true) {
                System.err.println("Adding a new question after resizing" 
                        + " to the system failed");
            }
        }
    }
    
    private void isRange(int index) {
        if (index < 0) {
            throw new IllegalArgumentException("Illegal index of element: "
                    + index);
        }
    }
    
    public Question get(int index) {
        isRange(index);
        return this.systemQuestions[index];        
    }
    
    public int size() {
        return this.size;
    }
}
